import CryptoJS from "crypto-js";
import {isString} from "@/rules/general";

/**
 *   示例
 *   const enc = AES_CBC_Encrypt(JSON.stringify({a:1,b:"a"}));
 *   console.log("加密：", enc);
 *   const dec = AES_CBC_Decrypt(enc);
 *   console.log("解密：", JSON.parse(dec));
 *
 *   参考：
 *   https://blog.csdn.net/m0_72167535/article/details/136089906
 *   https://juejin.cn/post/7382893339181613068#heading-12
 *   https://blog.csdn.net/m0_69892739/article/details/145039245
 *   https://blog.csdn.net/a666666000/article/details/143357602
 *   https://blog.csdn.net/weixin_61769998/article/details/140018717
 */
const KEY2: string = "{\"$super\":{\"$super\":{}},\"words\":[6357047,3538993,3145776,3735651,6619187,3473460,3604578,3604530,3604581,3735603,3670071,6684722,6619190,6357094,6357092,6422578],\"sigBytes\":64}"; // 秘钥
// const KEY = CryptoJS.lib.WordArray.random(16).toString(CryptoJS.enc.Hex)
// 生成随机的iv，长度为 16 字节
const iv: string = "a7e912827df0c0679ea21e9311fd7a7f";
/**
 * AES CBC（密码块链接模式） 加密
 * KEY:  需要前后端保持一致
 * mode: ECB  需要前后端保持一致
 * pad: Pkcs7 //前端 Pkcs7 对应 后端 Pkcs5
 */
export const AES_CBC_Encrypt = (plaintext: any) => {
  if(!isString(plaintext)) {
    plaintext = JSON.stringify(plaintext);
  }
  const srcs = CryptoJS.enc.Utf8.parse(plaintext);
  const keyInfo = JSON.parse(KEY2);
  const ivInfo = CryptoJS.enc.Utf8.parse(iv);
  const encrypted = CryptoJS.AES.encrypt(srcs, keyInfo, {
    iv: ivInfo,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7,
  });
  return CryptoJS.enc.Base64.stringify(encrypted.ciphertext);
};

/**
 * AES CBC（密码块链接模式） 解密
 */
export const AES_CBC_Decrypt = (jsonStr: any, isJson: boolean = true) => {
  if(!isString(jsonStr)) {
    throw new Error(`${jsonStr} 不是解密字符串。`);
  }
  const keyInfo = JSON.parse(KEY2);
  const ivInfo = CryptoJS.enc.Utf8.parse(iv);
  const base64  = CryptoJS.enc.Base64.parse(jsonStr);
  const srcs = CryptoJS.enc.Base64.stringify(base64);
  const decrypt = CryptoJS.AES.decrypt(srcs, keyInfo, {
    iv: ivInfo ,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
  });
  return isJson ? JSON.parse(decrypt.toString(CryptoJS.enc.Utf8)) : decrypt.toString(CryptoJS.enc.Utf8);
};

